package api

import (
	"context"
	"encoding/xml"
	"fmt"
	"io/ioutil"
	"regexp"
	"sort"
	"strings"
	"time"

	"dev.ixmxm.top/rms/codes"
	"dev.ixmxm.top/rms/managers/robotmanager"
	"dev.ixmxm.top/rms/model"
	"dev.ixmxm.top/rms/utils/base64"
	"dev.ixmxm.top/rms/utils/json"
	"dev.ixmxm.top/rms/utils/log"
	"dev.ixmxm.top/rms/utils/tools"
	"github.com/gin-gonic/gin"
)

// @Summary 获得所有工程名列表
// @Description
// @Accept application/json
// @Produce application/json
// @Success 0 {object} ResponseExampleList "返回数据格式"
// @Success 1 {object} []string "data数据：工程名集合"
// @Tags 地图
// @Router /map/get_project_names [get]
func (hg *HttpGateway) GetProjectNames(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	projectNameList := hg.dispatcher.GetProjectNameList()
	if len(projectNameList) == 0 {
		// log.ErrorfWithContext(ctx, "get project list error:%s", err.UnWrapError())
		return nil, codes.ErrProjectNamesIsNull
	}
	return projectNameList, nil
}

// @Summary 获得带AGV的工程Slam地图列表(并上传小车所有交通图)
// @Description
// @Accept application/json
// @Produce application/json
// @Param project_id query string true "工程ID"
// @Param agv_id query string true "小车ID"
// @Success 0 {object} ResponseExampleList "返回数据格式"
// @Success 1 {object} []model.SlamMap "data数据：AGV的工程Slam地图集合"
// @Tags 地图
// @Router /map/get_project_slam_maps [get]
func (hg *HttpGateway) GetProjectSlamMaps(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*getProjectParams)
	projectMapList := hg.dispatcher.GetProjectMapList(p.ProjectId)
	if p.AgvId != "" {
		subtasks, errSubtask := hg.dispatcher.TM().GetAllSubtaskFromDB(ctx)
		if errSubtask != nil {
			return nil, errSubtask.WithDetails("获取所有子任务失败")
		}
		for _, subtask := range subtasks {
			if subtask.AgvId == p.AgvId {
				return nil, codes.ErrTaskExists.WithDetails("存在运行的任务，不可更新该小车地图")
			}
		}
		hg.dispatcher.GetAgvProjectList(p.AgvId)
	}
	return projectMapList, nil
}

// @Summary 获得地图名称列表
// @Description
// @Accept application/json
// @Produce application/json
// @Success 0 {object} ResponseExampleList "返回数据格式"
// @Success 1 {object} []model.Map "data数据：地图名称集合"
// @Tags 地图
// @Router /map/get_map_names [get]
func (hg *HttpGateway) GetMapNames(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	maps, err := hg.dispatcher.TRM().GetAllMapFromDB(ctx)
	if err != nil {
		log.ErrorfWithContext(ctx, "get all maps error:%s", err.UnWrapError())
		return nil, err
	}
	sort.Sort(model.MapSlice(maps))
	return maps, nil
}

// @Summary 获得Base64地图数据
// @Description
// @Accept application/json
// @Produce application/json
// @Param map_name query string false "地图名称，为空时传全部"
// @Success 0 {object} ResponseExampleList "返回数据格式"
// @Success 1 {object} []getBase64Map "data数据：Base64地图集合"
// @Tags 地图
// @Router /map/get_base64_maps [get]
func (hg *HttpGateway) GetBase64Maps(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*getMapsParams)
	maps, err := hg.dispatcher.TRM().GetAllMapFromDB(ctx)
	if err != nil {
		log.ErrorfWithContext(ctx, "get all maps error:%s", err.UnWrapError())
		return nil, err
	}
	res := make([]getBase64Map, 0)
	for _, m := range maps {
		d := getBase64Map{
			MapName:       m.MapName,
			Base64MapData: m.RawBase64.String(),
		}
		if p.MapName == "" {
			res = append(res, d)
		} else {
			if p.MapName == m.MapName {
				res = append(res, d)
				break
			}
		}
	}

	return res, nil
}

// @Summary 获得json地图数据
// @Description
// @Accept application/json
// @Produce application/json
// @Param map_name query string false "地图名称，为空时传全部"
// @Success 0 {object} ResponseExampleList "返回数据格式"
// @Success 1 {object} []model.MapJson "data数据：json地图集合"
// @Tags 地图
// @Router /map/get_json_maps [get]
func (hg *HttpGateway) GetJsonMaps(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*getMapsParams)
	maps, err := hg.dispatcher.TRM().GetAllMapFromDB(ctx)
	if err != nil {
		log.ErrorfWithContext(ctx, "get all maps error:%s", err.UnWrapError())
		return nil, err
	}
	res := make([]model.MapJson, 0)
	for _, m := range maps {
		if p.MapName == "" {
			//mapData, err := model.MapBase64ToStruct(m.RawBase64)
			mapData := &model.MapXml{}
			err := json.BindFromString(m.MapDataJsonString, mapData)
			if err != nil {
				return nil, codes.ErrMapConvert.WithDetails(err.Error())
			}
			d := model.MapJson{
				MapName:     m.MapName,
				ProjectId:   m.ProjectId,
				TrafficName: m.TrafficName,
				MapData:     *mapData,
			}
			res = append(res, d)
		} else {
			if p.MapName == m.MapName {
				mapData := &model.MapXml{}
				err := json.BindFromString(m.MapDataJsonString, mapData)
				if err != nil {
					return nil, codes.ErrMapConvert.WithDetails(err.Error())
				}
				d := model.MapJson{
					MapName:     m.MapName,
					ProjectId:   m.ProjectId,
					TrafficName: m.TrafficName,
					MapData:     *mapData,
				}
				res = append(res, d)
				break
			}
		}
	}

	return res, nil
}

// @Summary 获得json地图数据
// @Description
// @Accept application/json
// @Produce application/json
// @Param name query string false "总览图名称，为空时传全部"
// @Success 0 {object} ResponseExampleList "返回数据格式"
// @Success 1 {object} []model.MapJson "data数据：json地图集合"
// @Tags 地图
// @Router /map/get_overview_json_maps [get]
func (hg *HttpGateway) GetOverViewJsonMaps(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*getOverviewMapParams)
	overviewMaps, err := hg.dispatcher.TRM().GetAllOverviewMapFromDB(ctx)
	if err != nil {
		log.ErrorfWithContext(ctx, "get all overview maps error:%s", err.UnWrapError())
		return nil, err
	}
	if p.Name != "" {
		for _, value := range overviewMaps {
			if value.Name == p.Name {
				return value, nil
			}
		}
	}
	return overviewMaps, nil
}

// @Summary 上传Base64地图(XML)
// @Description
// @Accept application/json
// @Produce application/json
// @Param body body uploadBase64MapsParams true "Base64地图(XML)"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 地图
// @Router /map/upload_base64_map [post]
func (hg *HttpGateway) UploadBase64Map(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*uploadBase64MapsParams)
	subtasks, err := hg.dispatcher.TM().GetAllSubtaskFromDB(ctx)
	if err != nil {
		return nil, err.WithDetails("获取所有子任务失败")
	}
	for _, subtask := range subtasks {
		if subtask.MapName == p.MapName {
			return nil, codes.ErrTaskExists.WithDetails("存在运行的任务，不可修改地图")
		}
	}
	mapData, mapXml, errParse := model.ParseMap(p.MapData.MustDecode())
	if errParse != nil {
		log.ErrorfWithContext(ctx, "map data parse error:%s", errParse.Error())
		return nil, codes.ErrInvalidParams.Wrap(errParse)
	}
	if p.ProjectId == "" || p.Name == "NULL" || p.MapName != fmt.Sprintf("%s@%s", p.ProjectId, p.Name) {
		log.Errorf("地图(%s)获取工程名称失败,不可为空", p.MapName)
		return nil, codes.ErrInvalidParams.WithDetails("地图取工程名称失败,不可为空")
	}
	m := &model.Map{
		MapName:           p.MapName,
		ProjectId:         p.ProjectId,
		TrafficName:       p.Name,
		MapData:           *mapData,
		RawBase64:         p.MapData,
		MapDataJsonString: json.DumpString(mapXml),
	}
	if errUpdate := hg.dispatcher.TRM().SaveMapToDB(ctx, m); errUpdate != nil {
		return nil, errUpdate
	}
	send := []*model.Map{m}
	for _, caller := range hg.dispatcher.GetAllCallers() {
		caller.SendMaps(ctx, send)
	}
	return nil, nil
}

// @Summary 上传json地图
// @Description
// @Accept application/json
// @Produce application/json
// @Param body body uploadJsonMapsParams true "json地图"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 地图
// @Router /map/upload_json_map [post]
func (hg *HttpGateway) UploadJsonMap(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*uploadJsonMapsParams)
	if p.MapName != p.ProjectId+"@"+p.TrafficName {
		return nil, codes.ErrMapNameNotMatch
	}
	//获得一键急停
	cfg := *hg.dispatcher.SystemConfig
	if !cfg.IsSoftStop {
		subtasks, err := hg.dispatcher.TM().GetAllSubtaskFromDB(ctx)
		if err != nil {
			return nil, err.WithDetails("获取所有子任务失败")
		}
		for _, subtask := range subtasks {
			if subtask.MapName == p.MapName {
				return nil, codes.ErrTaskExists.WithDetails("存在运行的任务，不可修改地图")
			}
		}
	}
	p.MapXml.MapInfo.MapName = p.MapName
	p.MapXml.MapInfo.ProjectId = p.ProjectId
	p.MapXml.MapInfo.TrafficName = p.TrafficName
	for i, n := range p.MapXml.Dots {
		if n.Type == model.NodeStation && n.LocationType == model.LocationGround {
			groundLocationGroup := hg.dispatcher.WMM().FindGroundLocation(p.MapName, n.Id)
			if groundLocationGroup == nil || len(groundLocationGroup.DepthPointId) == 0 {
				continue
			}
			dotsStr := strings.Split(n.BanDotID, ";")
			bans := make([]string, 0)
			banString := ""
			for j, dotStr := range dotsStr {
				if dotStr == "" || dotStr == "0" || tools.StringSliceIsContain(groundLocationGroup.DepthPointId, dotStr) {
					continue
				}
				bans = append(bans, dotStr)
				if j == len(dotsStr)-1 {
					banString += dotStr
				} else {
					banString += dotStr + ";"
				}

			}
			if strings.Compare(n.BanDotID, banString) != 0 {
				log.Infof("dot%d siteId:%s old:%s new:%s", i, n.Id, n.BanDotID, banString)
				p.MapXml.Dots[i].BanDotID = banString
			}
		}
	}
	mapXml, err := model.MapJsonToXml(p.MapXml)
	if err != nil {
		return nil, err
	}
	mapBase64 := base64.NewBase64FromString(mapXml)
	mapData, _, errParse := model.ParseMap(mapXml)
	if errParse != nil {
		log.ErrorfWithContext(ctx, "map data parse error:%s", errParse.Error())
		return nil, codes.ErrInvalidParams.Wrap(errParse)
	}
	if p.ProjectId == "" || p.MapName == "NULL" || p.MapName != fmt.Sprintf("%s@%s", p.ProjectId, p.TrafficName) {
		log.Errorf("地图(%s)获取工程名称失败,不可为空", p.MapName)
		return nil, codes.ErrInvalidParams.WithDetails("地图取工程名称失败,不可为空")
	}
	m := &model.Map{
		MapName:           p.MapName,
		ProjectId:         p.ProjectId,
		TrafficName:       p.TrafficName,
		MapData:           *mapData,
		RawBase64:         *mapBase64,
		MapDataJsonString: json.DumpString(p.MapXml),
	}
	log.Warnf("RawBase64 size:%d    MapDataJsonString size:%d", len(m.RawBase64), len(m.MapDataJsonString))
	//上传数据大小
	if errUpdate := hg.dispatcher.TRM().SaveMapToDB(ctx, m); errUpdate != nil {
		return nil, errUpdate
	}
	send := []*model.Map{m}
	for _, caller := range hg.dispatcher.GetAllCallers() {
		caller.SendMaps(ctx, send)
	}
	return nil, nil
}

// @Summary 上传json总览图
// @Description
// @Accept application/json
// @Produce application/json
// @Param body body uploadOverviewJsonMapParams true "json地图"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 地图
// @Router /map/upload_overview_json_map [post]
func (hg *HttpGateway) UploadOverViewJsonMap(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*uploadOverviewJsonMapParams)

	if errUpdate := hg.dispatcher.TRM().SaveOverviewMapToDB(ctx, &p.MapOverview); errUpdate != nil {
		return nil, errUpdate
	}

	return nil, nil
}

// @Summary 上传地图文件(xml文件)
// @Description
// @Param project_id formData string true "工程ID"
// @Param name formData string true "交通图名称"
// @Param xml formData file true "XML文件"
// @Produce  json
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 地图
// @Router /map/upload_file_map [post]
func (hg *HttpGateway) UploadFileMap(ctx context.Context, c *gin.Context) (interface{}, codes.Code) {
	projectId := c.Request.FormValue("project_id")
	// if projectId == "" {
	// 	return nil, codes.ErrDoHttpRequest.WithDetails("工程ID传入有误，不可为空")
	// }
	name := c.Request.FormValue("name")
	// if name == "" {
	// 	return nil, codes.ErrDoHttpRequest.WithDetails("交通图名称传入有误，不可为空")
	// }
	file, _, err := c.Request.FormFile("xml")
	if file == nil {
		return nil, codes.ErrDoHttpRequest.WithDetails("XML交通图文件传入有误，未找到XML").Wrap(err)
	}
	xmlBytes, err := ioutil.ReadAll(file)
	if xmlBytes == nil {
		return nil, codes.ErrDoHttpRequest.WithDetails("XML交通图文件传入有误，读取失败").Wrap(err)
	}
	rawMetadata := &model.MapXml{}
	if err := xml.Unmarshal(xmlBytes, rawMetadata); err != nil {
		return nil, codes.ErrDoHttpRequest.WithDetails("XML交通图文件传入有误，解析失败").Wrap(err)
	}

	if projectId != "" {
		rawMetadata.MapInfo.ProjectId = projectId
	}
	if name != "" {
		matched1, err := regexp.MatchString("^[a-zA-Z0-9_\u4e00-\u9fa5\\s·]+$", name)
		if err != nil || !matched1 {
			return nil, codes.ErrInvalidParams.WithDetails("交通图名不能有特殊字符！！！")
		}
		matched2, err := regexp.MatchString("^_|_$", name)
		if err != nil || matched2 {
			return nil, codes.ErrInvalidParams.WithDetails("交通图名首尾不能出现下划线！！！")
		}
		rawMetadata.MapInfo.TrafficName = name
	}
	rawMetadata.MapInfo.MapName = rawMetadata.MapInfo.ProjectId + "@" + rawMetadata.MapInfo.TrafficName
	cfg := *hg.dispatcher.SystemConfig
	if !cfg.IsSoftStop {
		subtasks, errSubtask := hg.dispatcher.TM().GetAllSubtaskFromDB(ctx)
		if errSubtask != nil {
			return nil, errSubtask.WithDetails("获取所有子任务失败")
		}
		for _, subtask := range subtasks {
			if subtask.MapName == rawMetadata.MapInfo.MapName {
				return nil, codes.ErrTaskExists.WithDetails("存在运行的任务，不可修改地图")
			}
		}
	}

	mapXmlString, err := model.MapJsonToXml(*rawMetadata)
	if err != nil {
		return nil, codes.ErrDoHttpRequest.WithDetails("XML交通图文件传入有误，解析失败").Wrap(err)
	}
	mapBase64 := base64.NewBase64FromString(mapXmlString)
	mapData, mapJson, errParse := model.ParseMap(mapXmlString)
	if errParse != nil {
		log.ErrorfWithContext(ctx, "map data parse error:%s", errParse.Error())
		return nil, codes.ErrInvalidParams.Wrap(errParse)
	}
	if rawMetadata.MapInfo.ProjectId == "" || rawMetadata.MapInfo.MapName == "NULL" || rawMetadata.MapInfo.MapName != fmt.Sprintf("%s@%s", rawMetadata.MapInfo.ProjectId, rawMetadata.MapInfo.TrafficName) {
		log.Errorf("地图(%s)获取工程名称失败,不可为空", rawMetadata.MapInfo.MapName)
		return nil, codes.ErrInvalidParams.WithDetails("地图取工程名称失败,不可为空")
	}
	m := &model.Map{
		MapName:           rawMetadata.MapInfo.MapName,
		ProjectId:         rawMetadata.MapInfo.ProjectId,
		TrafficName:       rawMetadata.MapInfo.TrafficName,
		MapData:           *mapData,
		RawBase64:         *mapBase64,
		MapDataJsonString: json.DumpString(mapJson),
	}
	if errUpdate := hg.dispatcher.TRM().SaveMapToDB(ctx, m); errUpdate != nil {
		return nil, errUpdate
	}
	send := []*model.Map{m}
	for _, caller := range hg.dispatcher.GetAllCallers() {
		caller.SendMaps(ctx, send)
	}
	return nil, nil
}

// @Summary 下载地图文件(xml文件)
// @Description
// @Accept application/json
// @Produce application/json
// @Param map_name query string true "地图名称"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 地图
// @Router /map/download_file_map [get]
func (hg *HttpGateway) DownloadFileMap(ctx context.Context, c *gin.Context) (interface{}, codes.Code) {
	mapName := c.Request.FormValue("map_name")
	if mapName == "" {
		return nil, codes.ErrDoHttpRequest.WithDetails("地图名称传入有误，不可为空")
	}
	mapData, err := hg.dispatcher.TRM().GetMapByNameFromDB(ctx, mapName)
	if err != nil {
		log.ErrorfWithContext(ctx, "get all maps error:%s", err.UnWrapError())
		return nil, err
	}
	mapXml := mapData.RawBase64.MustDecode()
	c.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%s.xml", mapData.MapName))
	c.Data(200, "application/octet-stream", []byte(mapXml))
	// c.Writer.Header().Add("Content-Type", "application/octet-stream")
	return nil, nil
}

// @Summary 获得所有锁定站点列表
// @Description
// @Accept application/json
// @Produce application/json
// @Success 0 {object} ResponseExampleList "返回数据格式"
// @Success 1 {object} []model.LockedSite "data数据：锁定站点集合"
// @Tags 地图
// @Router /map/get_locked_sites [get]
func (hg *HttpGateway) GetLockedSites(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	sites, err := hg.dispatcher.TRM().GetAllLockSiteFromDB(ctx)
	if err != nil {
		log.ErrorfWithContext(ctx, "get locked sites error:%s", err.Error())
		return nil, err
	}
	return sites, nil
}

// @Summary 点位锁定与释放
// @Description
// @Accept application/json
// @Produce application/json
// @Param body body stationOperateParams true "点位锁定与释放"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 地图
// @Router /map/operate_site [post]
func (hg *HttpGateway) OperateSite(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*stationOperateParams)
	switch p.OperateCMD {
	case SOCMDLock:
		return nil, hg.dispatcher.TRM().AddLockSiteToDB(ctx, p.MapName, p.SiteId)
	case SOCMDFree:
		return nil, hg.dispatcher.TRM().DeleteLockSiteFromDB(ctx, p.MapName, p.SiteId)
	}
	return nil, nil
}

// @Summary 获得所有锁定区域
// @Description
// @Accept application/json
// @Produce application/json
// @Success 0 {object} ResponseExampleList "返回数据格式"
// @Success 1 {object} []model.LockedArea "data数据：锁定区域集合"
// @Tags 地图
// @Router /map/get_locked_areas [get]
func (hg *HttpGateway) GetLockedAreas(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	areas, err := hg.dispatcher.TRM().GetAllLockAreaFromDB(ctx)
	if err != nil {
		log.ErrorfWithContext(ctx, "get locked sites error:%s", err.Error())
		return nil, err
	}
	return areas, nil
}

var lastOperateAreaTime time.Time

// @Summary 区域点位锁定与释放
// @Description
// @Accept application/json
// @Produce application/json
// @Param body body areaOperateParams true "区域锁定与释放"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 地图
// @Router /map/operate_area [post]
func (hg *HttpGateway) OperateArea(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*areaOperateParams)
	setLastTime := func() {
		lastOperateAreaTime = time.Now()
	}

	log.Warnf("API对地图：%s 交互区域ID：%s 执行操作：%d ", p.MapName, p.AreaId, p.OperateCMD)
	//当前时间减去上一次时间
	if time.Now().Sub(lastOperateAreaTime) < 2*time.Second {
		return nil, codes.ErrlowTimeInterval
	}
	defer setLastTime()
	switch p.OperateCMD {
	case SOCMDLock:
		nomalTaskOccupy := hg.dispatcher.GetNomalTaskOccupy(p.MapName)
		normalTaskLock := hg.dispatcher.GetNormalTaskLock(p.MapName)
		return nil, hg.dispatcher.TRM().AddLockAreaToDB(ctx, p.MapName, p.AreaId, p.MainTaskCode, nomalTaskOccupy, normalTaskLock)
	case SOCMDFree:
		return nil, hg.dispatcher.TRM().DeleteLockAreaFromDB(ctx, p.MapName, p.AreaId)
	}
	return nil, codes.ErrLockAreaCmdErr
}

// @Summary 删除地图
// @Description
// @Accept application/json
// @Produce application/json
// @Param map_name query string true "地图名称"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 地图
// @Router /map/delete_map [delete]
func (hg *HttpGateway) DeleteMap(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*mapDeleteParams)

	if hg.dispatcher.DM().MapUseInElevator(ctx, p.MapName) {
		return nil, codes.ErrMapInElevators
	}
	if robotmanager.MapUseInRobotsCache(ctx, p.MapName) {
		return nil, codes.ErrMapInRobots
	}

	status := model.TaskRunningStatus()
	status = append(status, model.TaskWaitingStatus()...)
	tasks, err := hg.dispatcher.TM().GetAllStatusTasksFromDB(context.Background(), status)
	if err != nil {
		return nil, codes.ErrDatabase
	}

	for _, t := range tasks {
		if t.MapName == p.MapName {
			return nil, codes.ErrTaskExists.WithDetails("存在运行的任务，不可删除地图")
		}
	}

	if err := hg.dispatcher.TRM().DeleteMapFromDB(ctx, p.MapName); err != nil {
		return nil, err
	}
	if err := hg.dispatcher.TRM().DeleteMapStandByPoint(ctx, p.MapName); err != nil {
		return nil, err
	}
	if err := hg.dispatcher.TRM().DeleteMapRelationByMapName(ctx, p.MapName); err != nil {
		return nil, err
	}
	return nil, hg.dispatcher.CM().DeleteMapChargePointFromDB(ctx, p.MapName)
}

// @Summary 删除总览图
// @Description
// @Accept application/json
// @Produce application/json
// @Param name query string true "地图名称"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 地图
// @Router /map/delete_overview_map [delete]
func (hg *HttpGateway) DeleteOverviewMap(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*mapOverviewDeleteParams)

	if err := hg.dispatcher.TRM().DeleteOverviewMapByName(ctx, p.Name); err != nil {
		return nil, err
	}
	return nil, nil
}

// @Summary 获得所有区域切换数据
// @Description
// @Accept application/json
// @Produce application/json
// @Success 0 {object} ResponseExampleList "返回数据格式"
// @Success 1 {object} []model.MapRelation "data数据：区域切换数据集合"
// @Tags 地图
// @Router /map/get_map_relations [get]
func (hg *HttpGateway) GetMapRelations(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	res, err := hg.dispatcher.TRM().GetAllMapRelationFromDB(ctx)
	if err != nil {
		log.ErrorfWithContext(ctx, "get all map relation error:%s", err.UnWrapError())
		return nil, err
	}
	return res, nil
}

// @Summary 保存区域切换
// @Description
// @Accept application/json
// @Produce application/json
// @Param body body setMapRelationParams true "区域切换"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 地图
// @Router /map/save_map_relation [post]
func (hg *HttpGateway) SaveMapRelation(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*setMapRelationParams)
	//查询所有的厂区切换数据
	res, err := hg.dispatcher.TRM().GetAllMapRelationByTypeFromDB(ctx, model.FactoryRealtion)
	if err != nil {
		return nil, err
	}
	//遍历过滤多个厂区切换为同一个点的情况
	for _, factoryRelation := range res {
		//过滤自己
		if p.FromMap == factoryRelation.FromMap && p.StartId == factoryRelation.StartId && p.ToMap == factoryRelation.ToMap && p.GoalId == factoryRelation.GoalId {
			continue
		}
		if (p.FromMap == factoryRelation.FromMap && p.StartId == factoryRelation.StartId) || (p.FromMap == factoryRelation.ToMap && p.StartId == factoryRelation.GoalId) {
			return nil, codes.ErrRelationPointAlreadyExists
		}
		if (p.ToMap == factoryRelation.FromMap && p.GoalId == factoryRelation.StartId) || (p.ToMap == factoryRelation.ToMap && p.GoalId == factoryRelation.GoalId) {
			return nil, codes.ErrRelationPointAlreadyExists
		}
	}
	//获得一键急停
	// cfg := *hg.dispatcher.SystemConfig
	// if !cfg.IsSoftStop {
	//判断
	subtasks, err := hg.dispatcher.TM().GetAllSubtaskFromDB(ctx)
	if err != nil {
		return nil, err.WithDetails("获取所有子任务失败")
	}
	for _, subtask := range subtasks {
		if subtask.MapName == p.FromMap || subtask.MapName == p.ToMap {
			return nil, codes.ErrTaskExists.WithDetails("关联地图存在运行的任务，不可修改地图")
		}
	}
	// }

	// tasks, _ := hg.dispatcher.TM().GetAllStatusTasksFromDB(context.Background(), model.TaskAssignStatus())
	// if len(tasks) > 0 {
	// 	return nil, codes.ErrActionTaskExists
	// }
	robots := robotmanager.GetAllRobotsFromCache()
	return nil, hg.dispatcher.TRM().AddMapRelationToDB(ctx, robots, p.FromMap, p.StartId, p.ToMap, p.GoalId, &p.MapRelation)
}

// @Summary 删除区域切换
// @Description
// @Accept application/json
// @Produce application/json
// @Param body body deleteMapRelationParams true "区域切换"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 地图
// @Router /map/delete_map_relation [delete]
func (hg *HttpGateway) DeleteMapRelation(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*deleteMapRelationParams)
	tasks, _ := hg.dispatcher.TM().GetAllStatusTasksFromDB(context.Background(), model.TaskAssignStatus())
	if len(tasks) > 0 {
		return nil, codes.ErrActionTaskExists
	}
	return nil, hg.dispatcher.TRM().DeleteMapRelationByFromMapAndToMap(ctx, p.FromMap, p.StartId, p.ToMap, p.GoalId)
}

// @Summary 释放厂区切换占用AGV
// @Description
// @Accept application/json
// @Produce application/json
// @Param body body releaseFactoryParams true "区域切换"
// @Success 0 {object} ResponseExample "返回数据格式"
// @Tags 地图
// @Router /map/release_factory_relation [post]
func (hg *HttpGateway) ReleaseFactoryRelation(ctx context.Context, params interface{}) (interface{}, codes.Code) {
	p := params.(*releaseFactoryParams)
	err := hg.dispatcher.TRM().ReleaseMapRelationPointStatus(ctx, p.FromMap, p.StartId, p.ToMap, p.GoalId)
	if err != nil {
		return nil, err
	}
	return nil, nil

}
